package com.tonyodev.fetch2.fetch;

import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.utils.Pair;

import com.tonyodev.fetch2.CompletedDownload;
import com.tonyodev.fetch2.Download;
import com.tonyodev.fetch2.Error;
import com.tonyodev.fetch2.FetchGroup;
import com.tonyodev.fetch2.FetchListener;
import com.tonyodev.fetch2.NetworkType;
import com.tonyodev.fetch2.Request;
import com.tonyodev.fetch2.Status;
import com.tonyodev.fetch2.database.DownloadInfo;
import com.tonyodev.fetch2core.DownloadBlock;
import com.tonyodev.fetch2core.Downloader;
import com.tonyodev.fetch2core.Extras;
import com.tonyodev.fetch2core.FetchObserver;
import com.tonyodev.fetch2core.FileResource;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @since 2021-05-20
 */
public interface FetchHandler extends Closeable {
    /**
     * init
     */
    void init();

    /**
     * enqueue
     *
     * @param request 1
     * @return 1
     */
    Pair<Download, Error> enqueue(Request request);

    /**
     * enqueue
     *
     * @param request 1
     * @return 1
     */
    List<Pair<Download, Error>> enqueue(List<Request> request);

    //  fun enqueueCompletedDownload(completedDownload: CompletedDownload): Download
    Download enqueueCompletedDownload(CompletedDownload completedDownload);

    // fun enqueueBatch(requests: List<Request>): List<Pair<DownloadInfo, Boolean>>
    List<Pair<DownloadInfo, Boolean>> enqueueBatch(List<Request> requests) throws IOException, DataAbilityRemoteException;

    //  fun enqueueCompletedDownloads(completedDownloads: List<CompletedDownload>): List<Download>
    List<Download> enqueueCompletedDownloads(List<CompletedDownload> completedDownloads);

    //  fun pause(ids: List<Int>): List<Download>
    List<Download> pause(List<Integer> ids);

    //  fun pausedGroup(id: Int): List<Download>
    List<Download> pausedGroup(int id);

    //  fun pauseAll(): List<Download>
    List<Download> pauseAll();

    //  fun freeze()
    void freeze();

    //  fun unfreeze()
    void unfreeze();

    //  fun resume(ids: List<Int>): List<Download>
    List<Download> resume(List<Integer> ids);

    //  fun resumeGroup(id: Int): List<Download>
    List<Download> resumeGroup(int id);

    //  fun resumeAll(): List<Download>
    List<Download> resumeAll();

    //  fun remove(ids: List<Int>): List<Download>
    List<Download> remove(List<Integer> ids);

    //  fun removeGroup(id: Int): List<Download>
    List<Download> removeGroup(int id);

    //  fun removeAll(): List<Download>
    List<Download> removeAll();

    //  fun removeAllWithStatus(status: Status): List<Download>
    List<Download> removeAllWithStatus(Status status);

    //  fun removeAllInGroupWithStatus(groupId: Int, statuses: List<Status>): List<Download>
    List<Download> removeAllInGroupWithStatus(int groupId, List<Status> statuses);

    //  fun delete(ids: List<Int>): List<Download>
    List<Download> delete(List<Integer> ids);

    //  fun deleteGroup(id: Int): List<Download>
    List<Download> deleteGroup(int id);

    //  fun deleteAll(): List<Download>
    List<Download> deleteAll();

    //  fun deleteAllWithStatus(status: Status): List<Download>
    List<Download> deleteAllWithStatus(Status status);

    //  fun deleteAllInGroupWithStatus(groupId: Int, statuses: List<Status>): List<Download>
    List<Download> deleteAllInGroupWithStatus(int groupId, List<Status> statuses);

    //  fun cancel(ids: List<Int>): List<Download>
    List<Download> cancel(List<Integer> ids);

    //  fun cancelGroup(id: Int): List<Download>
    List<Download> cancelGroup(int id);

    //  fun cancelAll(): List<Download>
    List<Download> cancelAll();

    //  fun retry(ids: List<Int>): List<Download>
    List<Download> retry(List<Integer> ids);

    //  fun updateRequest(requestId: Int, newRequest: Request): Pair<Download, Boolean>
    Pair<Download, Boolean> updateRequest(int requestId, Request newRequest);

    //  fun getDownloads(): List<Download>
    List<Download> getDownloads();

    //  fun getDownload(id: Int): Download?
    Download getDownload(int id);

    //  fun getDownloads(idList: List<Int>): List<Download>
    List<Download> getDownloads(List<Integer> idList);

    //  fun getDownloadsInGroup(id: Int): List<Download>
    List<Download> getDownloadsInGroup(int id);

    //  fun getDownloadsWithStatus(status: Status): List<Download>
    List<Download> getDownloadsWithStatus(Status status);

    // fun getAllGroupIds(): List<Int>
    List<Integer> getAllGroupIds();

    // fun getDownloadsByTag(tag: String): List<Download>
    List<Download> getDownloadsByTag(String tag);

    //  fun getDownloadsWithStatus(statuses: List<Status>): List<Download>
    List<Download> getDownloadsWithStatus(List<Status> statuses);

    //  fun getDownloadsInGroupWithStatus(groupId: Int, statuses: List<Status>): List<Download>
    List<Download> getDownloadsInGroupWithStatus(int groupId, List<Status> statuses);

    //  fun getDownloadsByRequestIdentifier(identifier: Long): List<Download>
    List<Download> getDownloadsByRequestIdentifier(Long identifier);

    //  fun setGlobalNetworkType(networkType: NetworkType)
    void setGlobalNetworkType(NetworkType networkType);

    //  fun enableLogging(enabled: Boolean)
    void enableLogging(boolean enabled);

    //  fun addListener(listener: FetchListener, notify: Boolean, autoStart: Boolean)
    void addListener(FetchListener listener, boolean notify, boolean autoStart);

    //  fun removeListener(listener: FetchListener)
    void removeListener(FetchListener listener);

    //  fun getDownloadBlocks(id: Int): List<DownloadBlock>
    List<DownloadBlock> getDownloadBlocks(int id);

    //  fun getContentLengthForRequest(request: Request, fromServer: Boolean): Long
    Long getContentLengthForRequest(Request request, boolean fromServer);

    /**
     * getServerResponse
     *
     * @param url 路径
     * @param header 1
     * @return 1
     * @throws IOException 1
     */
    Downloader.Response getServerResponse(String url, Map<String, String> header) throws IOException;

    //  fun getFetchFileServerCatalog(request: Request): List<FileResource>
    List<FileResource> getFetchFileServerCatalog(Request request);

    //  fun setDownloadConcurrentLimit(downloadConcurrentLimit: Int)
    void setDownloadConcurrentLimit(int downloadConcurrentLimit);

    //  fun replaceExtras(id: Int, extras: Extras): Download
    Download replaceExtras(int id, Extras extras);

    //  fun hasActiveDownloads(includeAddedDownloads: Boolean): Boolean
    boolean hasActiveDownloads(boolean includeAddedDownloads);

    //  fun getListenerSet(): Set<FetchListener>
    Set<FetchListener> getListenerSet();

    //  fun getPendingCount(): Long
    Long getPendingCount();

    //  fun renameCompletedDownloadFile(id: Int, newFileName: String): Download
    Download renameCompletedDownloadFile(int id, String newFileName);

    //  fun getFetchGroup(id: Int): FetchGroup
    FetchGroup getFetchGroup(int id);

    //  fun addFetchObserversForDownload(downloadId: Int, vararg  fetchObservers: FetchObserver<Download>)
    void addFetchObserversForDownload(int downloadId, FetchObserver<Download>... fetchObservers);

    //  fun removeFetchObserversForDownload(downloadId: Int, vararg fetchObservers: FetchObserver<Download>)
    void removeFetchObserversForDownload(int downloadId, FetchObserver<Download>... fetchObservers);

    //  fun resetAutoRetryAttempts(downloadId: Int, retryDownload: Boolean): Download?
    Download resetAutoRetryAttempts(int downloadId, boolean retryDownload);
}
